package com.yonyou.crm.cum.customer.ctrl;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Date;
import java.util.Random;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;

import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectResult;

public class OSSClientUtil {

	// 阿里云API的外网域名
	public static final String ENDPOINT = "oss-cn-beijing.aliyuncs.com";
	// 阿里云API的密钥Access Key ID
	public static final String ACCESS_KEY_ID = "LTAIDa0Tl3599ygR";
	// 阿里云API的密钥Access Key Secret
	public static final String ACCESS_KEY_SECRET = "Qc4dfroL1X7tOEpJE8JMnxPug3Tifh";
	// 阿里云API的bucket名称
	public static final String BACKET_NAME = "yonyoubucket";
	// log日志
	private final static Logger logger = LoggerFactory
			.getLogger(OSSClientUtil.class);

	/**
	 * 获取阿里云OSS客户端对象
	 * 
	 * @return ossClient
	 */
	public static OSSClient getOSSClient() {
		return new OSSClient(ENDPOINT, ACCESS_KEY_ID, ACCESS_KEY_SECRET);
	}

	/**
	 * 获取url地址
	 * 
	 * @param key
	 * @return
	 */
	public String getUrl(String key) {
		// 设置URL过期时间为10年 3600l* 1000*24*365*10
		Date expiration = new Date(new Date().getTime() + 3600l * 1000 * 24
				* 365 * 10);
		OSSClient ossClient = getOSSClient();
		URL url = ossClient.generatePresignedUrl(BACKET_NAME, key,
				expiration);// 生成URL
		if (url != null) {
			return url.toString();
		}
		return null;
	}

	/**
	 * 删除文件
	 * 
	 * @param key
	 *            Bucket下的文件的路径名+文件名 如："newfile/9865.jpg"
	 */
	public static void deleteFile(String wholeFileName) {
		OSSClient ossClient = getOSSClient();
		ossClient.deleteObject(BACKET_NAME, wholeFileName);
		logger.info("删除" +" BACKET:"+BACKET_NAME + " 下的文件 " + wholeFileName + " 成功");
	}

	/**
	 * 创建文件夹
	 * 
	 * @param ossClient
	 * @param bucketName
	 * @param folder
	 * @return
	 */
	public String createFolder(OSSClient ossClient, String bucketName,
			String folder) {
		// 文件夹名
		final String keySuffixWithSlash = folder;
		// 判断文件夹是否存在，不存在则创建
		if (!ossClient.doesObjectExist(bucketName, keySuffixWithSlash)) {
			// 创建文件夹
			ossClient.putObject(bucketName, keySuffixWithSlash,
					new ByteArrayInputStream(new byte[0]));
			// 得到文件夹名
			OSSObject object = ossClient.getObject(bucketName,
					keySuffixWithSlash);
			String fileDir = object.getKey();
			return fileDir;
		}
		return keySuffixWithSlash;
	}

	// 上传文件
	public String uploadImg2Oss(MultipartFile file) throws Exception {

		String originalFilename = file.getOriginalFilename();
		String substring = originalFilename.substring(
				originalFilename.lastIndexOf(".")).toLowerCase();
		Random random = new Random();
		String name = random.nextInt(10000) + System.currentTimeMillis()
				+ substring;
		try {
			InputStream inputStream = file.getInputStream();
			this.uploadFile2OSS(inputStream, name);
			return name;
		} catch (Exception e) {
			throw new IOException("图片上传失败");
		}
	}

	/**
	 * 上传到OSS服务器 如果同名文件会覆盖服务器上的
	 *
	 * @param instream
	 *            文件流
	 * @param fileName
	 *            文件名称 包括后缀名
	 * @return 出错返回"" ,唯一MD5数字签名
	 */
	public String uploadFile2OSS(InputStream instream, String fileName) {
		String ret = "";
		OSSClient ossClient = getOSSClient();
		try {
			// 创建上传Object的Metadata
			ObjectMetadata objectMetadata = new ObjectMetadata();
			objectMetadata.setContentLength(instream.available());
			objectMetadata.setCacheControl("no-cache");
			objectMetadata.setHeader("Pragma", "no-cache");
			objectMetadata.setContentType(getContentType(fileName));
			objectMetadata.setContentDisposition("inline;filename=" + fileName);
			// 上传文件
			PutObjectResult putResult = ossClient.putObject(BACKET_NAME, fileName, instream, objectMetadata);
			ret = putResult.getETag();
		} catch (IOException e) {
			logger.error(e.getMessage(), e);
		} finally {
			try {
				if (instream != null) {
					instream.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return ret;
	}

	/**
	 * 上传文件到阿里云
	 * @param wholeFileName 存储文件的完成路径：attachment/objType/objId/fileName
	 * @param file
	 * @return
	 */
	public static String uploadObject2OSS(String wholeFileName,File file) {
		String resultStr = null;
		OSSClient ossClient = getOSSClient();
		try {
			// 以输入流的形式上传文件
			InputStream is = new FileInputStream(file);
			String fileName = file.getName(); // 文件名
			Long fileSize = file.length(); // 文件大小

			// 创建上传Object的Metadata
			ObjectMetadata metadata = new ObjectMetadata();
			metadata.setContentLength(is.available()); // 上传的文件的长度
			metadata.setCacheControl("no-cache"); // 指定该Object被下载时的网页的缓存行为
			metadata.setHeader("Pragma", "no-cache"); // 指定该Object下设置Header
			metadata.setContentEncoding("utf-8"); // 指定该Object被下载时的内容编码格式
			metadata.setContentType(getContentType(fileName)); // 文件的MIME，定义文件的类型
			metadata.setContentDisposition("filename/filesize=" + fileName
					+ "/" + fileSize + "Byte."); // 指定该Object被下载时的名称（指示MINME用户代理如何显示附加的文件，打开或下载，及文件名称）

			// 上传文件 (上传文件流的形式)
			PutObjectResult putResult = ossClient.putObject(BACKET_NAME, wholeFileName, is, metadata);
			// 解析结果
			resultStr = putResult.getETag();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return resultStr;
	}

	/**
	 * 从阿里云下载文件 （以附件形式下载）
	 * 
	 * @param request
	 * @param response
	 */
	public void downLoadFile(HttpServletRequest request,
			HttpServletResponse response) {
		try {
			String fileid = request.getParameter("fileid").toString();// 从前台获取当前下载文件的id值（每个上传到阿里云的文件都会有一个独一无二的id值）
			String filename = request.getParameter("filename").toString();// 从前台获取要下载文件的文件名
			int i = filename.lastIndexOf("\\");
			filename = filename.substring(i + 1);

			OSSClient ossClient = getOSSClient();
			// 获取fileid对应的阿里云上的文件对象
			OSSObject ossObject = ossClient.getObject(BACKET_NAME, fileid);

			// 读Object内容 返回
			BufferedInputStream in = new BufferedInputStream(
					ossObject.getObjectContent());

			BufferedOutputStream out = new BufferedOutputStream(
					response.getOutputStream());
			// 通知浏览器以附件形式下载
			response.setHeader("Content-Disposition", "attachment;filename="
					+ URLEncoder.encode(filename, "utf-8"));

			byte[] car = new byte[1024];
			int L = 0;
			while ((L = in.read(car)) != -1) {
				out.write(car, 0, L);
			}
			if (out != null) {
				out.flush();
				out.close();
			}
			if (in != null) {
				in.close();
			}
			ossClient.shutdown();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 通过文件名判断并获取OSS服务文件上传时文件的contentType
	 * 
	 * @param fileName
	 *            文件名
	 * @return String 文件的contentType
	 */
	public static String getContentType(String fileName) {
		// 文件的后缀名
		String fileExtension = fileName.substring(fileName.lastIndexOf("."));
		if (".bmp".equalsIgnoreCase(fileExtension)) {
			return "image/bmp";
		}
		if (".gif".equalsIgnoreCase(fileExtension)) {
			return "image/gif";
		}
		if (".jpeg".equalsIgnoreCase(fileExtension)
				|| ".jpg".equalsIgnoreCase(fileExtension)
				|| ".png".equalsIgnoreCase(fileExtension)) {
			return "image/jpeg";
		}
		if (".png".equalsIgnoreCase(fileExtension)) {
			return "image/png";
		}
		if (".html".equalsIgnoreCase(fileExtension)) {
			return "text/html";
		}
		if (".txt".equalsIgnoreCase(fileExtension)) {
			return "text/plain";
		}
		if (".vsd".equalsIgnoreCase(fileExtension) 
				|| ".vsdx".equalsIgnoreCase(fileExtension)) {
			return "application/vnd.visio";
		}
		if (".ppt".equalsIgnoreCase(fileExtension)
				|| ".pptx".equalsIgnoreCase(fileExtension)) {
			return "application/vnd.ms-powerpoint";
		}
		if (".xls".equalsIgnoreCase(fileExtension)
				|| ".xlsx".equalsIgnoreCase(fileExtension)) {
			return "application/msexcel";
		}
		if (".doc".equalsIgnoreCase(fileExtension)
				|| ".docx".equalsIgnoreCase(fileExtension)) {
			return "application/msword";
		}
		if (".xml".equalsIgnoreCase(fileExtension)) {
			return "text/xml";
		}
		// 默认返回类型
		return "text/plain";
	}

	/**
	 * base64字符串转文件
	 * 
	 * @param base64
	 * @return
	 */
	public static File base64ToFile(String base64) {
		File file = null;
		String fileName = System.currentTimeMillis() + ".jpeg";
		FileOutputStream out = null;
		try {
			// 解码，然后将字节转换为文件
			file = new File("", fileName);
			if (!file.exists())
				file.createNewFile();
			byte[] bytes = Base64.decodeBase64(base64);// 将字符串转换为byte数组
			ByteArrayInputStream in = new ByteArrayInputStream(bytes);
			byte[] buffer = new byte[1024];
			out = new FileOutputStream(file);
			@SuppressWarnings("unused")
			int bytesum = 0;
			int byteread = 0;
			while ((byteread = in.read(buffer)) != -1) {
				bytesum += byteread;
				out.write(buffer, 0, byteread); // 文件写操作
			}
		} catch (IOException ioe) {
			ioe.printStackTrace();
		} finally {
			try {
				if (out != null) {
					out.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return file;
	}

	/**
	 * 文件转base64字符串
	 * 
	 * @param file
	 * @return
	 */
	public static String fileToBase64(File file) {
		String base64 = null;
		InputStream in = null;
		try {
			in = new FileInputStream(file);
			byte[] bytes = new byte[in.available()];
			in.read(bytes);
			base64 = new String(Base64.encodeBase64(bytes));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (in != null) {
					in.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return base64;
	}

}
